package edu.gatech.gro;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ExpandableListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import edu.gatech.gro.http.IResponseAdapter;
import edu.gatech.gro.model.ListGroup;
import edu.gatech.gro.model.ListItem;
import edu.gatech.gro.model.NamedList;
import edu.gatech.gro.model.ObjectResponse;

public class ItemDisplayActivity extends Activity {

	private static final String TAG = "ITEM_DISPLAY_ACTIVITY";

	private final IncomingHandler mHandler = new IncomingHandler();

	private static final int GOT_LIST = 0;
	private static final int GOT_CHECK = 1;

	private static final int LIST_ITEM_DELETED = 10;

	private static GroceryListManagerApplication app;

	private ExpandableListView mTree;
	private Button mAddItemButton;

	private AlertDialog mAlertDialog;
	private ProgressDialog mProgressList;
	private ProgressDialog mProgressDelete;

	private NamedList mCurrentList;

	private ItemAdapter mItemDisplayAdapter;

	private int mUserId;
	private int mListId;
	// private String mListName;
	private String mListNameClean;

	private CheckBox mLastCheck;
	private ProgressBar mLastProgress;
	private boolean mLastCheckStatus;
	private int mLastListItemDeletedGroupIndex;
	private int mLastListItemDeletedIndex;

	@Override
	public void onCreate(Bundle b) {
		super.onCreate(b);

		app = (GroceryListManagerApplication) getApplicationContext();

		setContentView(R.layout.items_manager);

		mTree = (ExpandableListView) findViewById(R.id.expandableListViewItems);

		Bundle extra = getIntent().getExtras();
		mUserId = extra.getInt("userId");
		mListId = extra.getInt("namedListId");
		// mListName = extra.getString("namedListName");
		mListNameClean = extra.getString("namedListNameClean");

		// Search Button
		mAddItemButton = (Button) findViewById(R.id.addItemButton);

		mAddItemButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				Log.d(TAG, "mAddItemButton clicked");
				displayItemAdderPanel();
			}
		});
	}

	@Override
	public void onResume() {
		super.onResume();
		waitForList();
	}

	private void waitForList() {
		if (mProgressList != null && mProgressList.isShowing()) {
			return;
		}

		mProgressList = ProgressDialog.show(ItemDisplayActivity.this, "", // this.getString(R.string.pleaseWait),
		    this.getString(R.string.progressList), true, false);

		app.getNamedList(mUserId, mListNameClean, mListListener);
	}

	private void waitForDeleteListItem(final ListItem item) {
		if (mProgressDelete != null && mProgressDelete.isShowing()) {
			return;
		}

		mProgressDelete = ProgressDialog.show(ItemDisplayActivity.this, "", // this.getString(R.string.pleaseWait),
		    this.getString(R.string.progressDelete), true, false);

		app.deleteListItem(mListNameClean, item, mListItemDeletedListener);
	}

	private void refreshList() {
		if (mCurrentList != null) {
			mItemDisplayAdapter = new ItemAdapter(mCurrentList);
			mTree.setAdapter(mItemDisplayAdapter);
		}
	}

	private void displayItemAdderPanel() {
		Intent i = new Intent(this, ItemLookUpActivity.class);
		i.putExtra("namedList_nameClean", mListNameClean);
		i.putExtra("namedList_id", mListId);
		startActivity(i);
	}

	private void alterCheck() {
		if (mLastCheck != null && mLastProgress != null) {
			mLastProgress.setVisibility(ProgressBar.INVISIBLE);
			mLastCheck.setChecked(mLastCheckStatus);
			mLastCheck.setEnabled(!mLastCheckStatus);
			mLastCheck.setVisibility(CheckBox.VISIBLE);
		}
	}

	private void deleteListItem(ListItem item) {
		if (mLastListItemDeletedGroupIndex > -1 && mLastListItemDeletedIndex > -1) {
			waitForDeleteListItem(item);
		}
	}

	/**
	 * Helper function to dismiss a progress dialog
	 * 
	 * @param theProgress
	 *          the progress dialog to dismiss
	 */
	private void dismissProgress(ProgressDialog theProgress) {
		if (theProgress != null && theProgress.isShowing()) {
			theProgress.dismiss();
		}
	}

	/**
	 * Handler of incoming messages from the Service
	 */
	private class IncomingHandler extends Handler {

		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
				case GOT_LIST:
					refreshList();
					break;
				case GOT_CHECK:
					alterCheck();
					break;
				case LIST_ITEM_DELETED:
					if (mLastListItemDeletedGroupIndex != -1 && mLastListItemDeletedIndex != -1) {
						mCurrentList.getItemGroups().get(mLastListItemDeletedGroupIndex).getItems().remove(mLastListItemDeletedIndex);
						if (mCurrentList.getItemGroups().get(mLastListItemDeletedGroupIndex).getItems().size() == 0) {
							mCurrentList.getItemGroups().remove(mLastListItemDeletedGroupIndex);
						}
						mItemDisplayAdapter.notifyDataSetChanged();
						mLastListItemDeletedGroupIndex = -1;
						mLastListItemDeletedIndex = -1;
					}
					break;
				default:
					super.handleMessage(msg);
					break;
			}
		}
	}

	private final IResponseAdapter mListListener = new IResponseAdapter() {

		@Override
		public void onResponse(ObjectResponse response) {
			dismissProgress(mProgressList);
			if (response.isSuccessful()) {
				mCurrentList = (NamedList) response.getData();
				Log.d(TAG, "Types received!");

				// Send a message to the activity to update the view (on the UI
				// thread)
				mHandler.sendEmptyMessage(GOT_LIST);
			} else {
				displayError(R.string.failRetriveListContentTitle, response.getErrorsAsString());
			}
		}
	};

	private final IResponseAdapter mCheckListener = new IResponseAdapter() {

		@Override
		public void onResponse(ObjectResponse response) {
			mLastCheckStatus = response.isSuccessful();
			mHandler.sendEmptyMessage(GOT_CHECK);
		}
	};

	private final IResponseAdapter mListItemDeletedListener = new IResponseAdapter() {

		@Override
		public void onResponse(ObjectResponse response) {
			dismissProgress(mProgressDelete);
			if (response.isSuccessful()) {
				mHandler.sendEmptyMessage(LIST_ITEM_DELETED);
			} else {
				displayError(R.string.failDeleteItemTitle, response.getErrorsAsString());
			}
		}
	};

	private void displayError(final int titleId, final String message) {
		mAlertDialog.setTitle(titleId);
		mAlertDialog.setMessage(message);
		mAlertDialog.show();
	}

	private class ItemAdapter extends BaseExpandableListAdapter {

		private static final String TAG = "ITEM_DISPLAY_ADAPTER";

		private final NamedList mCurrentList;

		public ItemAdapter(NamedList currentList) {
			super();
			this.mCurrentList = currentList;
		}

		@Override
		public ListItem getChild(int groupPosition, int childPosition) {
			return (ListItem) mCurrentList.getItemGroups().get(groupPosition).getItems().get(childPosition);
		}

		@Override
		public long getChildId(int groupPosition, int childPosition) {
			return mCurrentList.getItemGroups().get(groupPosition).getItems().get(childPosition).getId();
		}

		@Override
		public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
			View v = convertView;
			if (v == null) {
				LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				v = vi.inflate(R.layout.list_type_item, null);
			}
			final ListItem li = getChild(groupPosition, childPosition);
			if (li != null) {
				final TextView textQuantity = (TextView) v.findViewById(R.id.list_type_item_quantity);
				final TextView textName = (TextView) v.findViewById(R.id.list_type_item_name);
				final CheckBox checkbox = (CheckBox) v.findViewById(R.id.list_type_item_check);
				final ProgressBar progress = (ProgressBar) v.findViewById(R.id.list_type_item_progress);

				/*
				 * if it is checked, display the number of items bought otherwise,
				 * display the number of remaining items to buy.
				 */
				int q = li.isChecked() ? li.getQuantity() : li.getQuantity() - li.getCurrentQuantity();

				textName.setText(li.getName());
				textQuantity.setText(Integer.toString(q));
				checkbox.setChecked(li.isChecked());
				checkbox.setEnabled(!li.isChecked());
				checkbox.setOnClickListener(new View.OnClickListener() {

					@Override
					public void onClick(View v) {
						if (!li.isChecked()) {
							Log.d(TAG, "Checkbox clicked for item #" + li.getId());
							checkbox.setVisibility(CheckBox.INVISIBLE);
							progress.setVisibility(ProgressBar.VISIBLE);
							mLastCheck = checkbox;
							mLastProgress = progress;
							li.setChecked(true);
							li.setNamedListId(mCurrentList.getId());
							app.updateListItem(mCurrentList.getNameClean(), li, mCheckListener);
						}
					}
				});

				textName.setOnLongClickListener(new View.OnLongClickListener() {

					@Override
					public boolean onLongClick(View v) {
						deleteListItem(li);
						mLastListItemDeletedIndex = childPosition;
						mLastListItemDeletedGroupIndex = groupPosition;
						return false;
					}
				});
			}
			return v;
		}

		@Override
		public int getChildrenCount(int groupPosition) {
			return mCurrentList.getItemGroups().get(groupPosition).getItems().size();
		}

		@Override
		public ListGroup getGroup(int groupPosition) {
			return mCurrentList.getItemGroups().get(groupPosition);
		}

		@Override
		public int getGroupCount() {
			return mCurrentList.getItemGroups().size();
		}

		@Override
		public long getGroupId(int groupPosition) {
			return mCurrentList.getItemGroups().get(groupPosition).getId();
		}

		@Override
		public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
			View v = convertView;
			if (v == null) {
				LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				v = vi.inflate(R.layout.list_type, null);
			}
			final ListGroup g = getGroup(groupPosition);
			if (g != null) {
				TextView textName = (TextView) v.findViewById(R.id.list_type_name);
				TextView textCount = (TextView) v.findViewById(R.id.list_type_count);
				textName.setText(g.getName());
				textCount.setText(Integer.toString(g.getItems().size()));
			}
			return v;
		}

		@Override
		public boolean hasStableIds() {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public boolean isChildSelectable(int groupPosition, int childPosition) {
			// TODO Auto-generated method stub
			return false;
		}
	}
}
